package com.concurrence;


import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 *  读写锁的操作，获取与释放 高位读锁 16 ，低位写锁 16
 */
public class ReentrantRW {
    static ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
    static ReentrantReadWriteLock.ReadLock readLock = reentrantReadWriteLock.readLock();
    static ReentrantReadWriteLock.WriteLock writeLock = reentrantReadWriteLock.writeLock();

    public static void main(String[] args) throws InterruptedException {

        forReadAndWrite();
        manyLockAndOneUnLock();
        return;
    }

    private static void manyLockAndOneUnLock() throws InterruptedException {
        // 读写锁，分别加锁多次，释放一次
        Thread rThread = new Thread(new ReadeWorker(), "读线程");
        rThread.start();

        Thread.sleep(1000);

        Thread wThread = new Thread(new WriteWoeker(), "写线程");
        wThread.start();
        wThread.join();
    }

    private static void forReadAndWrite() {
        for (int i = 0; i < 10; i++) {
            new Thread(new WriteWoeker(), "写线程" + i).start();
            new Thread(new ReadeWorker(), "读线程" + i).start();
        }
    }

    static class WriteWoeker implements Runnable {

        @Override
        public void run() {
            writeLock.lock();
            System.out.println(Thread.currentThread().getName() + "开始了");
            // writeLock.lock();
            // System.out.println(Thread.currentThread().getName() + "写锁第二次"); // 必须要再次释放锁
            writeLock.unlock();
        }
    }

    static class ReadeWorker implements Runnable {

        @Override
        public void run() {
            int readHoldCount = reentrantReadWriteLock.getReadLockCount();
            System.out.println(readHoldCount);
            readLock.lock();
            // 一个线程第二次获取毒素哦 ，只来一次，不解锁，看写线程能否取得
            //  readLock.lock();
            System.out.println(Thread.currentThread().getName() + "开始了");

            readLock.unlock();
        }
    }
}
